package com.sl.biz.core.openapi;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.plugins.IgnoreStrategy;
import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper;
import com.sl.biz.modular.product.dao.entity.ProductDO;
import com.sl.biz.modular.product.service.ProductBizService;
import com.sl.biz.modular.restapi.dao.entity.ApiConfigDO;
import com.sl.biz.modular.restapi.dao.enums.ApiStatusCodeEnum;
import com.sl.biz.modular.restapi.service.ApiConfigBizService;
import org.apache.commons.lang3.StringUtils;
import org.springdoc.api.OpenApiResourceNotFoundException;
import org.springdoc.core.customizers.SpringDocCustomizers;
import org.springdoc.core.models.GroupedOpenApi;
import org.springdoc.core.properties.SpringDocConfigProperties;
import org.springdoc.core.providers.SpringDocProviders;
import org.springdoc.core.service.AbstractRequestService;
import org.springdoc.core.service.GenericResponseService;
import org.springdoc.core.service.OpenAPIService;
import org.springdoc.core.service.OperationService;
import org.springdoc.webmvc.api.MultipleOpenApiWebMvcResource;
import org.springdoc.webmvc.api.OpenApiActuatorResource;
import org.springdoc.webmvc.api.OpenApiResource;
import org.springdoc.webmvc.api.OpenApiWebMvcResource;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Optional;

import static org.springdoc.core.utils.Constants.ACTUATOR_DEFAULT_GROUP;

@RestController
public class CustomerMultipleOpenApiWebMvcResource extends MultipleOpenApiWebMvcResource {

    private final SpringDocConfigProperties springDocConfigProperties;

    private final ObjectFactory<OpenAPIService> defaultOpenAPIBuilder;

    private final AbstractRequestService requestBuilder;

    private final OperationService operationParser;

    private final GenericResponseService responseBuilder;

    private final SpringDocProviders springDocProviders;

    private final ApiConfigBizService apiConfigBizService;

    private final ProductBizService productBizService;


    /**
     * Instantiates a new Multiple open api resource.
     *
     * @param groupedOpenApis           the grouped open apis
     * @param defaultOpenAPIBuilder     the default open api builder
     * @param requestBuilder            the request builder
     * @param responseBuilder           the response builder
     * @param operationParser           the operation parser
     * @param springDocConfigProperties the spring doc config properties
     * @param springDocProviders        the spring doc providers
     * @param springDocCustomizers      the spring doc customizers
     */
    public CustomerMultipleOpenApiWebMvcResource(List<GroupedOpenApi> groupedOpenApis, ObjectFactory<OpenAPIService> defaultOpenAPIBuilder, AbstractRequestService requestBuilder,
                                                 GenericResponseService responseBuilder, OperationService operationParser,
                                                 SpringDocConfigProperties springDocConfigProperties, SpringDocProviders springDocProviders,
                                                 SpringDocCustomizers springDocCustomizers, ApiConfigBizService apiConfigBizService, ProductBizService productBizService) {
        super(groupedOpenApis, defaultOpenAPIBuilder, requestBuilder, responseBuilder, operationParser, springDocConfigProperties, springDocProviders, springDocCustomizers);
        this.springDocConfigProperties = springDocConfigProperties;
        this.defaultOpenAPIBuilder = defaultOpenAPIBuilder;
        this.requestBuilder = requestBuilder;
        this.operationParser = operationParser;
        this.responseBuilder = responseBuilder;
        this.springDocProviders = springDocProviders;
        this.apiConfigBizService = apiConfigBizService;
        this.productBizService = productBizService;
    }


    /**
     * Gets open api resource or throw.
     *
     * @param group the group
     * @return the open api resource or throw
     */
    @Override
    protected OpenApiResource getOpenApiResourceOrThrow(String group) {
        OpenApiResource openApiResourceOrThrow = null;
        try {
            openApiResourceOrThrow = super.getOpenApiResourceOrThrow(group);
        } catch (Exception e) {

            //找不到，从数据库里面找
            openApiResourceOrThrow = buildOpenApiResourceByDb(group);
        }

        return openApiResourceOrThrow;

    }

    private OpenApiResource buildOpenApiResourceByDb(String group) {
        IgnoreStrategy ignoreStrategy = IgnoreStrategy.builder().tenantLine(true).build();
        InterceptorIgnoreHelper.handle(ignoreStrategy);
        ProductDO productDO = productBizService.queryByCode(group);
        if (ObjectUtil.isNull(productDO)) {
            return null;
        }

//        ApiConfigDO apiConfigDO = new ApiConfigDO();
//        apiConfigDO.setProductId(productDO.getId());
//        apiConfigDO.setApiStatusCode(ApiStatusCodeEnum.ONLINE.getCode());
//        List<ApiConfigDO> list = apiConfigBizService.list(apiConfigDO);
        InterceptorIgnoreHelper.clearIgnoreStrategy();

//        if(CollUtil.isEmpty(list)){
//            return null;
//        }
//        for (ApiConfigDO configDO : list) {
//
//        }
        GroupedOpenApi.Builder builder = GroupedOpenApi.builder();
//        if (!CollectionUtils.isEmpty(elt.getPackagesToScan()))
        builder.packagesToScan(this.getClass().getPackageName());
//        if (!CollectionUtils.isEmpty(elt.getPathsToMatch()))
//            builder.pathsToMatch(elt.getPathsToMatch().toArray(new String[0]));
//        if (!CollectionUtils.isEmpty(elt.getProducesToMatch()))
//            builder.producesToMatch(elt.getProducesToMatch().toArray(new String[0]));
//        if (!CollectionUtils.isEmpty(elt.getConsumesToMatch()))
//            builder.consumesToMatch(elt.getConsumesToMatch().toArray(new String[0]));
//        if (!CollectionUtils.isEmpty(elt.getHeadersToMatch()))
//            builder.headersToMatch(elt.getHeadersToMatch().toArray(new String[0]));
//        if (!CollectionUtils.isEmpty(elt.getPathsToExclude()))
//            builder.pathsToExclude(elt.getPathsToExclude().toArray(new String[0]));
//        if (!CollectionUtils.isEmpty(elt.getPackagesToExclude()))
//            builder.packagesToExclude(elt.getPackagesToExclude().toArray(new String[0]));
//        if (StringUtils.isNotEmpty(elt.getDisplayName()))
        builder.displayName(productDO.getProductCode());
        GroupedOpenApi item = builder.group(productDO.getProductCode()).build();

        boolean preLoadingEnabled = springDocConfigProperties.isPreLoadingEnabled();
        springDocConfigProperties.setPreLoadingEnabled(false);
        CustomerOpenApiWebMvcResource openApiWebMvcResource = new CustomerOpenApiWebMvcResource(item.getGroup(),
                defaultOpenAPIBuilder,
                requestBuilder,
                responseBuilder,
                operationParser,
                springDocConfigProperties, springDocProviders,
                new SpringDocCustomizers(Optional.of(item.getOpenApiCustomizers()), Optional.of(item.getOperationCustomizers()),
                        Optional.of(item.getRouterOperationCustomizers()), Optional.of(item.getOpenApiMethodFilters())),
                apiConfigBizService,
                productBizService
        );
        springDocConfigProperties.setPreLoadingEnabled(preLoadingEnabled);
        return openApiWebMvcResource;
    }

}
